/*
 * // +-------------------------------------------------------------------------------------------------
 * // |                 有你就好 [ 有节骨乃坚，无心品自端 ]     <http://encoding.wang>
 * // +-------------------------------------------------------------------------------------------------
 * // |                             独在异乡为异客         每逢佳节倍思亲
 * // +-------------------------------------------------------------------------------------------------
 * // |                 联系:   <707069100@qq.com>      <http://weibo.com/513778937>
 * // +-------------------------------------------------------------------------------------------------
 */

// -----------------------------------------------------------------------------------------------------
// +----------------------------------------------------------------------------------------------------
// |                   ErYang出品 属于小极品          共同学习    共同进步
// +----------------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------------


package wang.encoding.mroot.common.util


import org.springframework.beans.BeansException
import org.springframework.context.ApplicationContext
import org.springframework.context.ApplicationContextAware
import org.springframework.stereotype.Component
import wang.encoding.mroot.common.exception.UtilException

/**
 * SpringContext 工具类
 *
 * @author ErYang
 */
@Component("springContextUtil")
class SpringContextUtil : ApplicationContextAware {

    companion object {

        /**
         * Spring 应用上下文环境
         */
        private var applicationContext: ApplicationContext? = null

        /**
         * 定义一个静态私有变量
         * 不初始化 不使用 final 关键字 使用 volatile 保证了多线程访问时 instance 变量的可见性
         * 避免了 instance 初始化时其他变量属性还没赋值完时 被另外线程调用
         */
        @Volatile
        private var springContextUtil: SpringContextUtil? = null

        // -------------------------------------------------------------------------------------------------

        /**
         * 定义一个共有的静态方法，返回该类型实例
         *
         * @return SpringContextUtil
         */
        @JvmStatic
        fun getSpringContextUtil(): SpringContextUtil? {
            // 对象实例化时与否判断（不使用同步代码块 instance 不等于 null 时 直接返回对象 提高运行效率）
            if (null == springContextUtil) {
                // 同步代码块（对象未初始化时 使用同步代码块 保证多线程访问时对象在第一次创建后 不再重复被创建）
                synchronized(SpringContextUtil::class.java) {
                    //未初始化，则初始instance变量
                    if (null == springContextUtil) {
                        springContextUtil = SpringContextUtil()
                    }
                }
            }
            return springContextUtil
        }
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 得到 applicationContext
     *
     * @return applicationContext
     */
    fun getApplicationContext(): ApplicationContext? {
        return applicationContext
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 实现ApplicationContextAware接口的回调方法 设置上下文环境
     *
     * @param applicationContext applicationContext
     * @throws BeansException BeansException
     */
    @Throws(BeansException::class)
    override fun setApplicationContext(applicationContext: ApplicationContext) {
        if (null == SpringContextUtil.applicationContext) {
            SpringContextUtil.applicationContext = applicationContext
        }
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 获取对象
     *
     * @param name name
     * @param <T>  Object 一个以所给名字注册的bean的实例
     * @return bean
     * @throws UtilException
    </T> */
    @Suppress("UNCHECKED_CAST")
    @Throws(UtilException::class)
    fun <T> getBean(name: String): T {
        return applicationContext!!.getBean(name) as T
    }

    // -------------------------------------------------------------------------------------------------

}

// -----------------------------------------------------------------------------------------------------

// End SpringContextUtil class

/* End of file SpringContextUtil.kt */
/* Location: ./src/main/kotlin/wang/encoding/mroot/common/util/SpringContextUtil.kt */

// -----------------------------------------------------------------------------------------------------
// +----------------------------------------------------------------------------------------------------
// |                           ErYang出品 属于小极品  O(∩_∩)O~~   共同学习    共同进步
// +----------------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------------